#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#include <vita2d.h>
#include "vita2d_ext.h"

#include "shaders.h"

#include "shader/texture_v.h"
#include "shader/texture_f.h"
#include "shader/sharp_bilinear_v.h"
#include "shader/sharp_bilinear_f.h"
#include "shader/sharp_bilinear_simple_f.h"
#include "shader/sharp_bilinear_simple_v.h"
#include "shader/lcd3x_v.h"
#include "shader/lcd3x_f.h"
#include "shader/advanced_aa_v.h"
#include "shader/advanced_aa_f.h"

extern float _vita2d_ortho_matrix[4 * 4];

vita2d_shader *lcd3x_shader, *sharp_bilinear_simple_shader, *sharp_bilinear_shader, *advanced_aa_shader;

void initShaders()
{
    lcd3x_shader = vita2d_create_shader((SceGxmProgram *)lcd3x_v, (SceGxmProgram *)lcd3x_f);
    sharp_bilinear_simple_shader = vita2d_create_shader((SceGxmProgram *)sharp_bilinear_simple_v, (SceGxmProgram *)sharp_bilinear_simple_f);
    sharp_bilinear_shader = vita2d_create_shader((SceGxmProgram *)sharp_bilinear_v, (SceGxmProgram *)sharp_bilinear_f);
    advanced_aa_shader = vita2d_create_shader((SceGxmProgram *)advanced_aa_v, (SceGxmProgram *)advanced_aa_f);
}

void finishShaders()
{
    vita2d_free_shader(lcd3x_shader);
    vita2d_free_shader(sharp_bilinear_simple_shader);
    vita2d_free_shader(sharp_bilinear_shader);
    vita2d_free_shader(advanced_aa_shader);
}

void vita2d_draw_texture_part_scale_rotate_shader(const vita2d_texture *texture, const vita2d_shader *shader, float x, float y,
                                                  float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, float rad)
{
    vita2d_set_shader(shader);

    float *texture_size = (float *)vita2d_pool_memalign(2 * sizeof(float), sizeof(float));
    texture_size[0] = (float)vita2d_texture_get_width(texture);
    texture_size[1] = (float)vita2d_texture_get_height(texture);

    float *output_size = (float *)vita2d_pool_memalign(2 * sizeof(float), sizeof(float));
    output_size[0] = (float)vita2d_texture_get_width(texture) * x_scale;
    output_size[1] = (float)vita2d_texture_get_height(texture) * y_scale;

    vita2d_set_vertex_uniform(shader, "IN.texture_size", texture_size, 2);
    vita2d_set_vertex_uniform(shader, "IN.video_size", texture_size, 2);
    vita2d_set_vertex_uniform(shader, "IN.output_size", output_size, 2);

    vita2d_set_fragment_uniform(shader, "IN.texture_size", texture_size, 2);
    vita2d_set_fragment_uniform(shader, "IN.video_size", texture_size, 2);
    vita2d_set_fragment_uniform(shader, "IN.output_size", output_size, 2);
    
    vita2d_set_wvp_uniform(shader, _vita2d_ortho_matrix);

    vita2d_draw_texture_part_scale_rotate_generic(texture, x, y, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, rad);
}